package com.yami.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.yami.shop.bean.model.MeltCloudGroup;
import com.yami.shop.bean.model.MeltCloudUser;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Json;
import com.yami.shop.dto.user.GroupNotificationMessageDTO;
import com.yami.shop.service.MeltCloudGroupService;
import com.yami.shop.service.MeltCloudUserService;
import com.yami.shop.util.SendUtil;
import com.yami.shop.vo.group.UserIdVo;
import com.yami.shop.vo.message.message.GroupMessageVo;
import com.yami.shop.vo.message.message.PrivateMessageVo;
import com.yami.shop.vo.message.message.UltraGroupMessageVo;
import io.rong.RongCloud;
import io.rong.messages.GroupNotificationMessage;
import io.rong.messages.ImgMessage;
import io.rong.messages.InfoNtfMessage;
import io.rong.messages.TxtMessage;
import io.rong.methods.message._private.Private;
import io.rong.methods.message.chatroom.Chatroom;
import io.rong.methods.message.discussion.Discussion;
import io.rong.methods.message.group.Group;
import io.rong.methods.message.history.History;
import io.rong.methods.message.system.MsgSystem;
import io.rong.methods.message.ultragroup.UltraGroup;
import io.rong.models.message.GroupMessage;
import io.rong.models.message.PrivateMessage;
import io.rong.models.message.PushExt;
import io.rong.models.message.UltraGroupMessage;
import io.rong.models.response.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.yami.shop.common.response.ServerResponseEntity.success;


/**
 * 消息
 */
@Service
@Slf4j
public class RongYunMsgServiceImpl {

    @Autowired
    private RongCloud sysRongCloud;

    private MsgSystem system;
    private Private Private;
    private Group group;
    private Discussion discussion;
    private Chatroom chatroom;
    private UltraGroup ultraGroup;
    private History history;
    @Autowired
    private MeltCloudGroupService groupService;
    @Autowired
    private MeltCloudUserService userService;

    @PostConstruct
    public void init() {
        this.system = sysRongCloud.message.system;
        this.Private = sysRongCloud.message.msgPrivate;
        this.group = sysRongCloud.message.group;
        this.discussion = sysRongCloud.message.discussion;
        this.chatroom = sysRongCloud.message.chatroom;
        this.ultraGroup = sysRongCloud.message.ultraGroup;
        this.history = sysRongCloud.message.history;
    }


    /**
     * 消息管理-群聊消息发送-普通消息发送
     *
     * @param systemVo
     * @return
     */
    public ServerResponseEntity<String> publishGroup(GroupMessageVo systemVo) throws Exception {
        PushExt pushExt = null;
        if (ObjectUtil.isNotEmpty(systemVo.getAdvicePutExtVo())) {
            pushExt = PushExt.build(systemVo.getAdvicePutExtVo().getTitle(), systemVo.getAdvicePutExtVo().getForceShowPushContent(),
                    new PushExt.HW(systemVo.getAdvicePutExtVo().getHwChannelId(), systemVo.getAdvicePutExtVo().getImportance()), new PushExt.VIVO(systemVo.getAdvicePutExtVo().getClassification()),
                    new PushExt.APNs(systemVo.getAdvicePutExtVo().getThreadId(), systemVo.getAdvicePutExtVo().getApnsCollapseId()),
                    new PushExt.OPPO(systemVo.getAdvicePutExtVo().getOppoChannelId()));
        }
        List<String> targets = systemVo.getTargetId();
        List<MeltCloudGroup> list = groupService.listByIds(targets);
        if(list==null||targets.size()!=list.size()){
            throw new YamiShopBindException("发送群聊消息异常:群id参数异常");
        }
        Map<String, List<MeltCloudGroup>> groupMap = list.stream().collect(Collectors.groupingBy(MeltCloudGroup::getType));
        List<MeltCloudGroup> groupList = groupMap.get("0");
        if (CollUtil.isNotEmpty(groupList)) {
            String[] targetId = groupList.stream().map(g -> g.getId().toString()).toArray(String[]::new);
            GroupMessage systemMessage = new GroupMessage()
                    .setSenderId(systemVo.getSenderId())
                    .setTargetId(targetId)
                    .setObjectName(systemVo.getObjectName())
                    .setPushContent(systemVo.getPushContent())
                    .setPushData(systemVo.getPushData())
                    .setPushExt(pushExt)
                    .setIsPersisted(systemVo.getIsPersisted())
                    .setIsIncludeSender(systemVo.getIsIncludeSender())
                    .setContentAvailable(systemVo.getContentAvailable());
            if ("RC:TxtMsg".equals(systemVo.getObjectName())) {
                TxtMessage voiceMessage = new TxtMessage(systemVo.getContent().getContent(), systemVo.getContent().getExtra());
                systemMessage.setContent(voiceMessage);
            } else if ("RC:ImgMsg".equals(systemVo.getObjectName())) {
                ImgMessage voiceMessage = new ImgMessage("", systemVo.getContent().getExtra(), systemVo.getContent().getImageUri());
                systemMessage.setContent(voiceMessage);
            }
            ResponseResult result = group.send(systemMessage);
            if (!SendUtil.requestSuccess(result))
                throw new YamiShopBindException("发送群聊消息异常:" + result.getErrorMessage());
        }
        List<MeltCloudGroup> ultraGroupList = groupMap.get("1");
        if (CollUtil.isNotEmpty(ultraGroupList)) {
            String[] targetId = ultraGroupList.stream().map(g -> g.getId().toString()).toArray(String[]::new);
            UltraGroupMessage message = new UltraGroupMessage()
                    .setSenderId(systemVo.getSenderId())
                    .setTargetId(targetId)
                    .setObjectName(systemVo.getObjectName())
                    .setPushContent(systemVo.getPushContent())
                    .setPushData(systemVo.getPushData())
                    .setPushExt(pushExt)
                    .setIsPersisted(systemVo.getIsPersisted())
                    .setBusChannel("RCDefault")
                    .setContentAvailable(systemVo.getContentAvailable());
            if ("RC:TxtMsg".equals(systemVo.getObjectName())) {
                TxtMessage voiceMessage = new TxtMessage(systemVo.getContent().getContent(), systemVo.getContent().getExtra());
                message.setContent(voiceMessage);
            } else if ("RC:ImgMsg".equals(systemVo.getObjectName())) {
                ImgMessage voiceMessage = new ImgMessage("", systemVo.getContent().getExtra(), systemVo.getContent().getImageUri());
                message.setContent(voiceMessage);
            }
            ResponseResult result = ultraGroup.send(message);
            if (!SendUtil.requestSuccess(result))
                throw new YamiShopBindException("发送群聊消息异常:" + result.getErrorMessage());
        }
        return success();
    }

    /**
     * 发送群组通知消息
     *
     * @return
     */
    public ServerResponseEntity<String> sendGroupAdvice(GroupNotificationMessageDTO dto) throws Exception {
        Map<String, Object> data = Maps.newHashMap();
        data.put("operatorNickname", "系统");
        List<String> targets = dto.getTargetId();
        String[] targetId = targets.toArray(new String[targets.size()]);
        List<String> toUserIds = dto.getToUserId();
        GroupNotificationMessage groupMessage = new GroupNotificationMessage(dto.getOperatorUserId(), dto.getOperation(), data, dto.getMessage(), dto.getExtra());
        GroupMessage message = new GroupMessage()
                .setSenderId(dto.getSenderId())
                .setTargetId(targetId)
                .setObjectName(StrUtil.isNotEmpty(dto.getObjectName())?dto.getObjectName():groupMessage.getType())//类型为默认系统普通消息 RC:GrpNtf和红包消息 S:SRpm
                .setIsIncludeSender(Objects.isNull(dto.getIsIncludeSender())?0:dto.getIsIncludeSender());
        log.info("=======群聊消息发送========");
        if(ObjectUtil.isNotNull(toUserIds)){ 
            String[] toUserId = toUserIds.toArray(new String[toUserIds.size()]);
            message.setToUserId(toUserId);
            message.setIsPersisted(1);
            groupMessage.setExtra(dto.getExtra());
            message.setContent(groupMessage);
            ResponseResult result = group.sendDirection(message);
            log.info("=========群聊消息发送结果：" + JSON.toJSONString(result));
            if (SendUtil.requestSuccess(result)) 
                return success();
        }else{
            message.setContent(groupMessage);
            ResponseResult result = group.send(message);
            log.info("=========群聊消息发送结果：" + JSON.toJSONString(result));
            if (SendUtil.requestSuccess(result)) 
                return success();
        }
        throw new YamiShopBindException("发送群组通知消息失败");
    }
    
    /**
     * 发送超级群组通知消息
     *
     * @return
     */
    public ServerResponseEntity<String> sendUltraGroupAdvice(GroupNotificationMessageDTO dto) throws Exception {
        Map<String, Object> data = Maps.newHashMap();
        data.put("operatorNickname", "系统");
        List<String> targets = dto.getTargetId();
        String[] targetId = targets.toArray(new String[targets.size()]);
        log.info("=======超级群聊消息发送========");
        GroupNotificationMessage groupMessage = new GroupNotificationMessage(dto.getOperatorUserId(), dto.getOperation(), data, dto.getMessage(), dto.getExtra());
        UltraGroupMessage message = new UltraGroupMessage()
                .setSenderId(dto.getSenderId())
                .setTargetId(targetId)
                .setObjectName(StrUtil.isNotEmpty(dto.getObjectName()) ? dto.getObjectName() : groupMessage.getType())
                .setContent(groupMessage)
                .setBusChannel(dto.getChannelId())
                .setIsPersisted(1);
        ResponseResult result = ultraGroup.send(message);
        log.info("=========超级群聊消息发送结果：" + JSON.toJSONString(result));
        if (SendUtil.requestSuccess(result)) return success();
        throw new YamiShopBindException("超级群聊-发送通知消息失败");
    }


    /**
     * 消息管理-发送单聊消息-普通消息发送
     *
     * @param privateMessageVo
     * @return
     */
    public ServerResponseEntity<String> privatePublish(PrivateMessageVo privateMessageVo) throws Exception {
        List<String> targets = privateMessageVo.getTargetId();
        String[] targetId = targets.toArray(new String[targets.size()]);
        List<MeltCloudUser> list = userService.listByIds(targets);
        if(list==null||targets.size()!=list.size()){
            throw new YamiShopBindException("发送消息异常:用户id参数异常");
        }
//        TxtMessage voiceMessage = new TxtMessage(privateMessageVo.getContent().getContent(), privateMessageVo.getContent().getExtra(), privateMessageVo.getContent().getImageUri());
        PrivateMessage privateMessage = new PrivateMessage()
                .setSenderId(privateMessageVo.getSenderId())
                .setTargetId(targetId)
                .setObjectName(privateMessageVo.getObjectName())
//                .setContent(voiceMessage)
                .setPushData(privateMessageVo.getPushData())
                .setPushExt(Json.toJsonString(privateMessageVo.getPushExtVo()))
                .setCount(privateMessageVo.getCount())
                .setVerifyBlacklist(privateMessageVo.getVerifyBlacklist())
                .setIsPersisted(privateMessageVo.getIsPersisted())
                .setIsIncludeSender(privateMessageVo.getIsIncludeSender());

        if("RC:TxtMsg".equals(privateMessageVo.getObjectName())){
            TxtMessage voiceMessage = new TxtMessage(privateMessageVo.getContent().getContent(), privateMessageVo.getContent().getExtra());
            privateMessage.setContent(voiceMessage);
        }else if("RC:ImgMsg".equals(privateMessageVo.getObjectName())){
            ImgMessage voiceMessage = new ImgMessage("",privateMessageVo.getContent().getExtra(),privateMessageVo.getContent().getImageUri());
            privateMessage.setContent(voiceMessage);
        }
        ResponseResult result = Private.send(privateMessage);
        if (SendUtil.requestSuccess(result))
            return success();
        throw new YamiShopBindException("发送单聊消息异常");
    }


    /**
     * 消息管理-发送单聊消息-小灰条消息发送
     *
     * @param privateMessageVo
     * @return
     */
    public ServerResponseEntity<String> privatePublishInfoNtf(PrivateMessageVo privateMessageVo) throws Exception {
        List<String> targets = privateMessageVo.getTargetId();
        String[] targetId = targets.toArray(new String[targets.size()]);
        InfoNtfMessage voiceMessage = new InfoNtfMessage(privateMessageVo.getContent().getContent(), privateMessageVo.getContent().getExtra());
        PrivateMessage privateMessage = new PrivateMessage()
                .setSenderId(privateMessageVo.getSenderId())
                .setTargetId(targetId)
                .setObjectName(StrUtil.isNotEmpty(privateMessageVo.getObjectName())?privateMessageVo.getObjectName():voiceMessage.getType())//类型为默认系统普通消息 RC:InfoNtf和红包消息 S:SRpm
                .setContent(voiceMessage)
                .setPushData(privateMessageVo.getPushData())
                .setPushExt(Json.toJsonString(privateMessageVo.getPushExtVo()))
                .setCount(privateMessageVo.getCount())
                .setVerifyBlacklist(privateMessageVo.getVerifyBlacklist())
                .setIsPersisted(privateMessageVo.getIsPersisted())
                .setIsIncludeSender(Objects.isNull(privateMessageVo.getIsIncludeSender())?0:privateMessageVo.getIsIncludeSender());
        ResponseResult result = Private.send(privateMessage);
        if (SendUtil.requestSuccess(result))
            return success();
        throw new YamiShopBindException("发送小灰条消息异常");
    }

    /**
     * 清除历史消息
     *
     * @param ultraGroupMessageVo
     * @return
     */
    public ServerResponseEntity<String> historyClean(UltraGroupMessageVo ultraGroupMessageVo) throws Exception {
        ResponseResult result = history.clean(ultraGroupMessageVo.getConversationType(), ultraGroupMessageVo.getFromUserId(), ultraGroupMessageVo.getTargetId(), ultraGroupMessageVo.getMsgTimestamp());
        if (SendUtil.requestSuccess(result))
            return success();
        throw new YamiShopBindException("清除历史消息失败");
    }
}
